import type { PaginationProps } from "ant-design-vue";
import { computed, Ref, ref, UnwrapRef } from "vue";
import type { PaginationParam, PaginationResult, OrderRule, TableRecord, SearchModel } from "/@/api/models";
import { useI18n } from "/@/locales/useI18n";
const DEFAULT_PAGE_SIZE = 10;

export interface UsePaginationOptions<T = TableRecord, K = SearchModel> {
  reqApi: (params: PaginationParam<K>) => Promise<PaginationResult<T> | null>;
  initPageSize?: number;
  loadFilter?: (data: UnwrapRef<T[]>) => UnwrapRef<T[]>;
  simple?: boolean;
}

export function usePagination<T = TableRecord, K = SearchModel>({
  reqApi,
  initPageSize,
  loadFilter,
  simple,
}: UsePaginationOptions<T, K>) {
  const loading = ref(false);
  const current = ref(1);
  const total = ref(0);
  const pageSize = ref(initPageSize || DEFAULT_PAGE_SIZE);
  const pageData = ref<T[]>([]);

  let sortOrder: OrderRule | "" = "";
  let sortField = "";
  let searchModel: Ref<SearchModel> = ref({});

  async function refreshPagination(params?: PaginationParam<K>): Promise<boolean> {
    params = params || {};
    if (params.pageNum) {
      current.value = params.pageNum || 1;
    }
    if (params.pageSize) {
      pageSize.value = params.pageSize;
    }
    if (params.order) {
      sortOrder = params.order;
    } else if (params.order === null) {
      sortOrder = "";
    }
    if (params.sort) {
      sortField = params.sort;
    } else if (params.sort === null) {
      sortField = "";
    }
    if (params.model) {
      Object.assign(searchModel.value, params.model);
    } else if (params.model === null) {
      searchModel.value = {};
    }
    loading.value = true;
    const result = await reqApi(
      Object.assign(
        {
          pageNum: current.value,
          pageSize: pageSize.value,
          // model: searchModel.value,
          sort: sortField,
          order: sortOrder,
        },
        searchModel.value
      )
    );
    if (result) {
      total.value = +result.total;
      let data = result.list || result.rows || [];
      if (loadFilter) {
        data = loadFilter(data);
      }
      pageData.value = data;
    }
    loading.value = false;
    return !!result;
  }
  const { t } = useI18n();
  const pagination = computed<PaginationProps>(() => ({
    total: total.value,
    current: current.value,
    pageSize: pageSize.value,
    showSizeChanger: true,
    size: "small",
    simple,
    showTotal(total, range) {
      return t("common.paginationInfo", {
        start: range[0],
        end: range[1],
        total,
      });
    },
    onChange: (pageNum, pageSize) => {
      refreshPagination({
        pageNum,
        pageSize,
      });
    },
  }));

  return {
    refreshPagination,
    current,
    pageSize,
    pageData,
    total,
    loading,
    pagination,
    searchModel,
  };
}
